"""
测试报告生成模块
包含用于生成 HTML 格式测试报告的 ReportGenerator 类
"""

import os
from datetime import datetime
import logging
from io import BytesIO
import base64


class ReportGenerator:
    @staticmethod
    def generate_html_report(test_results, success_cases, failed_cases, skipped_cases, total_cases, report_title):
        """
        生成 HTML 格式的测试报告

        参数:
            test_results (list): 测试结果列表，包含每个测试步骤的 TestResult 对象
            success_cases (int): 成功用例数
            failed_cases (int): 失败用例数
            skipped_cases (int): 跳过用例数
            total_cases (int): 总用例数
            report_title (str): 测试报告标题

        返回:
            str: 生成的测试报告文件路径

        报告生成流程:
        1. 计算基础统计数据（成功率等）
        2. 计算总执行时间和各个步骤的执行时间
        3. 准备模板数据
        4. 读取 HTML 模板并填充数据
        5. 保存生成的报告文件
        """
        try:
            # 1. 计算基础统计数据
            success_count = success_cases
            failed_count = failed_cases
            skipped_count = skipped_cases
            pass_rate = round((success_count / total_cases * 100), 2) if total_cases else 0

            # 2. 计算总执行时间
            if test_results:
                try:
                    first_time = datetime.strptime(test_results[0].timestamp, '%Y-%m-%d %H:%M:%S')
                    last_time = datetime.strptime(test_results[-1].timestamp, '%Y-%m-%d %H:%M:%S')
                    total_duration = format(round((last_time - first_time).total_seconds(), 3), '.3f')
                except ValueError:
                    total_duration = '0.000'
            else:
                total_duration = '0.000'

            # 获取步骤执行时间数据
            case_step_labels, step_durations = ReportGenerator._calculate_step_durations(test_results)

            # 4. 准备模板数据
            template_data = {
                'title': report_title,  # 修改：使用用户输入的报告标题
                'test_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'total_duration': total_duration,
                'total_cases': total_cases,
                'pass_rate': pass_rate,
                'passed_cases': success_count,
                'failed_cases': failed_count,
                'skipped_cases': skipped_count,
                'case_step_labels': str(case_step_labels),
                'step_durations': str(step_durations),
                'test_cases_content': ReportGenerator._generate_test_cases_content(test_results)
            }

            # 5. 读取模板并生成报告
            template_path = os.path.join('templates', 'report_template.html')
            with open(template_path, 'r', encoding='utf-8') as f:
                template_content = f.read()

            html_content = template_content.format(**template_data)

            # 6. 保存报告
            report_dir = "test_reports"
            if not os.path.exists(report_dir):
                os.makedirs(report_dir)

            report_path = os.path.join(report_dir, f"test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html")
            with open(report_path, 'w', encoding='utf-8') as f:
                f.write(html_content)

            return report_path

        except Exception as e:
            logging.error(f"生成报告失败: {str(e)}")
            raise

    @staticmethod
    def _generate_test_cases_content(test_results):
        """生成测试用例详细内容的HTML"""
        content = []
        current_case_id = None
        case_steps = []

        for result in test_results:
            if current_case_id != result.case_id:
                if case_steps:
                    content.append(ReportGenerator._generate_case_html(current_case_id, case_steps))
                    case_steps = []
                current_case_id = result.case_id
            case_steps.append(result)

        if case_steps:
            content.append(ReportGenerator._generate_case_html(current_case_id, case_steps))

        return '\n'.join(content)

    @staticmethod
    def _generate_case_html(case_id, steps):
        """生成单个测试用例的HTML内容"""
        case_status = 'pass' if all(s.status == 'success' for s in steps) else 'fail'

        html_parts = [f'''
        <div class="test-case">
            <h3>测试用例: {case_id}</h3>
            <p>测试点: {steps[0].test_point}</p>
            <div class="status-badge status-{case_status}">
                {"通过" if case_status == "pass" else "失败"}
            </div>
        ''']

        for step in steps:
            html_parts.append(f'''
            <div class="test-step">
                <h4>步骤 {step.step_number}: {step.step_desc}</h4>
                <span class="status-badge status-{case_status}">
                    {"✓ 成功" if step.status == "success" else "✗ 失败"}
                </span>
                <span class="timestamp">{step.timestamp}</span>
            ''')

            if step.error_msg:
                html_parts.append(f'''
                <div class="error-message">
                    <p>错误信息: {step.error_msg}</p>
                </div>
                ''')

            if step.screenshot:
                html_parts.append(f'''
                <div class="screenshot-container">
                    <img class="screenshot" 
                         src="data:image/png;base64,{step.screenshot}" 
                         onclick="showImage(this.src)" 
                         alt="测试截图">
                </div>
                ''')

            html_parts.append('</div>')

        html_parts.append('</div>')
        return '\n'.join(html_parts)

    @staticmethod
    def _calculate_step_durations(test_results):
        """计算步骤执行时间数据"""
        case_step_labels = []
        step_durations = []

        for result in test_results:
            try:
                timestamp = datetime.strptime(result.timestamp, '%Y-%m-%d %H:%M:%S')
                case_step_labels.append(f"Case {result.case_id} Step {result.step_number}")
                step_durations.append(float(timestamp.strftime('%S.%f')))
            except ValueError:
                case_step_labels.append(f"Case {result.case_id} Step {result.step_number}")
                step_durations.append(0.0)

        return case_step_labels, step_durations
